﻿/**
 * Peter
 * Created by: Peter Development Team
 *    http://peter.codeplex.com/
 * 
 * GNU General Public License version 2 (GPLv2)
 *    http://peter.codeplex.com/license
 *
 *  This code is provided on an AS IS basis, with no WARRANTIES,
 *  CONDITIONS or GUARANTEES of any kind.
 *
 **/

using System.Windows;
using System.Windows.Input;
using Peter.Common;
using Peter.Common.Controls;
using Peter.Logic;

namespace Peter.View
{
   /// <summary>
   /// Interaction logic for ViewEditor.xaml
   /// </summary>
   public partial class ViewEditor
   {
      private ModelEditor m_Model;

      /// <summary>
      /// Initializes a new editor view.
      /// </summary>
      public ViewEditor ()
      {
         InitializeComponent ();
         this.DataContextChanged += this.OnDataContextChanged;
         this.Loaded += this.DoneLoad;
      }

      /// <summary>
      /// Occurs when the control is done loading.
      /// </summary>
      /// <param name="sender">This</param>
      /// <param name="e">RoutedEventArgs</param>
      private void DoneLoad (object sender, RoutedEventArgs e)
      {
         if (this.m_Model != null)
            this.m_Model.Editor.Focus ();
      }

      /// <summary>
      /// Occurs when the data context changes.
      /// </summary>
      /// <param name="sender">This</param>
      /// <param name="e">DependencyPropertyChangedEventArgs</param>
      private void OnDataContextChanged (object sender, DependencyPropertyChangedEventArgs e)
      {
         this.m_Model = this.DataContext as ModelEditor;
         if (this.m_Model != null)
         {
            this.DataContextChanged -= this.OnDataContextChanged;
            this.m_Model.Editor.Focus ();
         }
         this.CommandBindings.Add (new CommandBinding (ApplicationCommands.Find, OnApplicationFind));
         this.CommandBindings.Add (new CommandBinding (PeterApplicationCommands.GotoLine, OnGotoLine));
         this.CommandBindings.Add (new CommandBinding (PeterApplicationCommands.FindNext, OnFindNext));
         this.CommandBindings.Add (new CommandBinding (PeterApplicationCommands.FindPrevious, OnFindPrevious));
         this.CommandBindings.Add (new CommandBinding (PeterApplicationCommands.Replace, OnReplace, CanReplace));
         this.CommandBindings.Add (new CommandBinding (PeterApplicationCommands.ReplaceAll, OnReplaceAll, CanReplace));
      }

      /// <summary>
      /// Occurs when the goto line hot key is pressed.
      /// </summary>
      /// <param name="sender">Application command sender.</param>
      /// <param name="e">ExecutedRoutedEventArgs</param>
      private void OnGotoLine (object sender, ExecutedRoutedEventArgs e)
      {
         e.Handled = true;
         if (this.m_Model != null)
         {
            this.m_Model.IsGotoLineVisible = true;
            this.GotoTextBox.Focus ();
         }
      }

      /// <summary>
      /// Occurs when the find application command is executed.
      /// </summary>
      /// <param name="sender">Issuer of the command.</param>
      /// <param name="e">ExecutedRoutedEventArgs</param>
      private void OnApplicationFind (object sender, ExecutedRoutedEventArgs e)
      {
         e.Handled = true;
         if (this.m_Model != null)
         {
            this.m_Model.IsFindBarVisible = true;
            this.m_Model.FindBarOpening ();
         }
         this.FindTextBox.Focus ();
         this.FindTextBox.SelectAll();
      }

      /// <summary>
      /// Occurs when the find next application command is executed.
      /// </summary>
      /// <param name="sender">Issuer of the command.</param>
      /// <param name="e">ExecutedRoutedEventArgs</param>
      private void OnFindNext (object sender, ExecutedRoutedEventArgs e)
      {
         e.Handled = true;
         if (this.m_Model != null)
            this.m_Model.FindNext ();
      }

      /// <summary>
      /// Occurs when the find previous application command is executed.
      /// </summary>
      /// <param name="sender">Issuer of the command.</param>
      /// <param name="e">ExecutedRoutedEventArgs</param>
      private void OnFindPrevious (object sender, ExecutedRoutedEventArgs e)
      {
         e.Handled = true;
         if (this.m_Model != null)
            this.m_Model.FindPrevious ();
      }

      /// <summary>
      /// Checks to see if the replace command can execute.
      /// </summary>
      /// <param name="sender">This</param>
      /// <param name="e">CanExecuteRoutedEventArgs</param>
      private void CanReplace (object sender, CanExecuteRoutedEventArgs e)
      {
         var canDo = false;
         e.Handled = true;
         if (this.m_Model != null)
            canDo = !string.IsNullOrWhiteSpace (this.m_Model.FindText);
         e.CanExecute = canDo;
      }

      /// <summary>
      /// Executes the replace all command.
      /// </summary>
      /// <param name="sender">This</param>
      /// <param name="e">ExecutedRoutedEventArgs</param>
      private void OnReplaceAll (object sender, ExecutedRoutedEventArgs e)
      {
         e.Handled = true;
         if (this.m_Model != null)
            this.m_Model.ReplaceAll ();
      }

      /// <summary>
      /// Executes the replace command.
      /// </summary>
      /// <param name="sender">This</param>
      /// <param name="e">ExecutedRoutedEventArgs</param>
      private void OnReplace (object sender, ExecutedRoutedEventArgs e)
      {
         e.Handled = true;
         if (this.m_Model != null)
            this.m_Model.Replace ();
      }

      /// <summary>
      /// Occurs when a key is pressed down in the search box.
      /// </summary>
      /// <param name="sender">Search text box.</param>
      /// <param name="e">KeyEventArgs</param>
      private void OnSearchKeyDown (object sender, KeyEventArgs e)
      {
         if (e.Key == Key.Enter && this.m_Model != null)
         {
            e.Handled = true;
            this.m_Model.FindNext ();
         }
      }

      /// <summary>
      /// Occurs when a key is pressed in the goto line box.
      /// </summary>
      /// <param name="sender">Goto line text box.</param>
      /// <param name="e">KeyEventArgs</param>
      private void OnGotoLineKeyDown (object sender, KeyEventArgs e)
      {
         if (e.Key == Key.Enter && this.m_Model != null)
         {
            e.Handled = true;
            this.m_Model.GotoLine ();
         }
         else if (e.Key == Key.Escape && this.m_Model != null)
         {
            e.Handled = true;
            this.m_Model.HideGotoLine ();
         }
         else if (!((e.Key >= Key.D0 && e.Key <= Key.D9) ||
                  (e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9)))
            e.Handled = true;
      }

      /// <summary>
      /// Occurs when the goto line button is clicked.
      /// </summary>
      /// <param name="sender">Goto line button.</param>
      /// <param name="e">RoutedEventArgs</param>
      private void OnGotoLineClick (object sender, RoutedEventArgs e)
      {
         if (this.m_Model != null)
         {
            this.m_Model.GotoLine ();
         }
      }

      private void OnInsightNavigation (object sender, RoutedEventArgs e)
      {
         var line = e.OriginalSource as InsightLine;
         if (line != null && this.m_Model != null)
         {
            this.m_Model.GotoLine (line.LineNumber, line.Column);
         }
      }
   }
}
